package com.murong.ai.coder.infrastructure.view;

import com.murong.ai.coder.domain.database.AfterSqlExecuteService;
import com.murong.ai.coder.domain.database.PreSqlExecuteService;
import com.murong.ai.coder.entity.DbConfig;
import com.murong.ai.coder.entity.GlobalProperties;
import com.murong.ai.coder.infrastructure.msgcode.CrResult;
import com.murong.ai.coder.infrastructure.repository.po.TableRecordPO;
import com.murong.ai.coder.infrastructure.util.MrSpringContextHolder;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

public class SqlExecWindow extends JFrame {
    private JComboBox<String> envComboBox;
    private JTextArea sqlTextArea;
    private JButton execButton;
    private JTable resultTable;
    private JScrollPane tableScrollPane;
    private JPanel panel;
    private Map<String, DbConfig> envDbConfigMap = new HashMap<>();

    public SqlExecWindow(GlobalProperties globalProperties) {
        // 初始化环境配置（请根据实际情况填写）
        List<GlobalProperties.Env> envList = globalProperties.getEnvironments().getEnvList();
        for (GlobalProperties.Env env : envList) {
            envDbConfigMap.put(env.getName(), env.getDatasource().toDbConfig());
        }
        // 可继续添加更多环境
        initUI();
    }

    private void initUI() {
        setTitle("SQL 可视化执行工具");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(750, 350);
        setLocationRelativeTo(null);

        panel = new JPanel(new BorderLayout(10, 10));

        // 顶部环境选择
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        envComboBox = new JComboBox<>(envDbConfigMap.keySet().toArray(new String[0]));
        topPanel.add(new JLabel("选择环境:"));
        topPanel.add(envComboBox);
        execButton = new JButton("执行");
        topPanel.add(execButton);
        panel.add(topPanel, BorderLayout.NORTH);

        // 中部 SQL 输入
        JPanel centerPanel = new JPanel(new BorderLayout(5, 5));
        sqlTextArea = new JTextArea(5, 60);
        JScrollPane sqlScrollPane = new JScrollPane(sqlTextArea);
        centerPanel.add(sqlScrollPane, BorderLayout.CENTER);
        panel.add(centerPanel, BorderLayout.CENTER);

        // 结果表格
        resultTable = new JTable();
        tableScrollPane = new JScrollPane(resultTable);
        tableScrollPane.setPreferredSize(new Dimension(780, 250));
        // panel.add(tableScrollPane, BorderLayout.SOUTH); // 初始化时不添加

        // 监听执行按钮
        execButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeSql();
            }
        });

        // 主体布局
        getContentPane().add(panel);
        setVisible(true);
    }

    private void executeSql() {
        String env = (String) envComboBox.getSelectedItem();
        String sql = sqlTextArea.getText().trim();
        if (sql.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入 SQL 语句！", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        DbConfig config = envDbConfigMap.get(env);
        if (config == null) {
            JOptionPane.showMessageDialog(this, "未找到该环境的数据库配置！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        try {
            Class.forName(config.getDriver());
            try (Connection conn = DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword())) {
                if (sql.toLowerCase().startsWith("select")) {
                    try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
                        showResultSet(rs);
                    }
                } else {

                    //执行前分析数据并存储记录
                    PreSqlExecuteService serv = MrSpringContextHolder.getBean(PreSqlExecuteService.class);
                    CrResult<TableRecordPO> crResult = serv.handleSql(sql, config);

                    if(crResult!=null&&crResult.isResult()) {
                        // 拆分SQL脚本，支持多条SQL（如建表+建索引）
                        String[] sqlStatements = splitSqlStatements(sql);
                        try (Statement stmt = conn.createStatement()) {
                            for (String singleSql : sqlStatements) {
                                if (singleSql.trim().isEmpty()) continue;
                                stmt.executeUpdate(singleSql);
                            }
                        }catch (SQLException e) {
                            if(crResult.getData()!=null) {
                                TableRecordPO recordPO = crResult.getData();
                                AfterSqlExecuteService aftServ = MrSpringContextHolder.getBean(AfterSqlExecuteService.class);
                                aftServ.updateError(recordPO);
                            }
                            throw e;
                        }

                        // 非select语句，移除结果表格
                        if (tableScrollPane.getParent() != null) {
                            panel.remove(tableScrollPane);
                            panel.revalidate();
                            panel.repaint();
                        }

                        if(crResult.getData()!=null) {
                            //执行后更新记录并根据存储数据生成代码
                            TableRecordPO recordPO = crResult.getData();
                            AfterSqlExecuteService aftServ = MrSpringContextHolder.getBean(AfterSqlExecuteService.class);
                            aftServ.handleRecord(recordPO);
                        }
                        // 清空SQL输入框
                        sqlTextArea.setText("");
                        JOptionPane.showMessageDialog(this, "执行成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
                    }
                }
            }
        } catch (Exception ex) {
            // 出错时也移除结果表格
            if (tableScrollPane.getParent() != null) {
                panel.remove(tableScrollPane);
                panel.revalidate();
                panel.repaint();
            }
            JOptionPane.showMessageDialog(this, "执行出错：" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }
    }

    private void showResultSet(ResultSet rs) throws SQLException {
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();
        Vector<String> columnNames = new Vector<>();
        for (int i = 1; i <= columnCount; i++) {
            columnNames.add(metaData.getColumnName(i));
        }
        Vector<Vector<Object>> data = new Vector<>();
        while (rs.next()) {
            Vector<Object> row = new Vector<>();
            for (int i = 1; i <= columnCount; i++) {
                row.add(rs.getObject(i));
            }
            data.add(row);
        }
        if (data.size() > 0) {
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            resultTable.setModel(model);
            if (tableScrollPane.getParent() == null) {
                panel.add(tableScrollPane, BorderLayout.SOUTH);
            }
            panel.revalidate();
            panel.repaint();
        } else {
            // 没有数据，移除结果表格
            if (tableScrollPane.getParent() != null) {
                panel.remove(tableScrollPane);
                panel.revalidate();
                panel.repaint();
            }
            JOptionPane.showMessageDialog(this, "查询无数据！", "提示", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    // 工具方法：安全拆分SQL脚本，避免字符串和注释中的分号
    private String[] splitSqlStatements(String sqlScript) {
        // 简单实现：仅按分号拆分，忽略分号在字符串/注释内的情况
        // 如需更严谨可用正则或第三方库
        return sqlScript.split(";\\s*(?=([^']*'[^']*')*[^']*$)");
    }
} 